package org.xm.sk.controller.dbase;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.data.domain.Page;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.xm.sk.exception.DataNotFoundException;
import org.xm.sk.exception.RequestParamterException;
import org.xm.sk.service.data.BaseService;
import org.xm.sk.service.security.XmUser;
import org.xm.sk.vo.Base;
import org.xm.sk.vo.e.WorksStatus;
import org.xm.sk.vo.e.WorksType;
import org.xm.sk.vo.ob.Ids;
import org.xm.sk.vo.ob.MapList;
import org.xm.sk.vo.ob.PageConf;
import org.xm.sk.vo.ob.ResultMsg;
import org.xm.sk.vo.ob.WorksInfo;
import org.xm.sk.vo.tb.Hairdresser;
import org.xm.sk.vo.tb.Image;
import org.xm.sk.vo.tb.Works;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;

@SuppressWarnings("unchecked")
@Api(tags = { "works" })
@RestController
@RequestMapping(value="/workses")
public class WorksController {
    
    @Autowired
    private MessageSource messages;
    @Autowired
    private BaseService<Hairdresser> hairdresserService;
    @Autowired
    private BaseService<Works> worksService;
    @Autowired
    private BaseService<Image> imageService;
    
    @ApiOperation(value="创建作品", notes="根据works对象创建作品，使用此接口需要ADMIN权限")
    @ApiImplicitParam(name = "worksInfo", value = "作品信息实体对象", required = true, dataType = "WorksInfo")
    @PreAuthorize("hasRole('ADMIN')")
    @RequestMapping(value="", method=RequestMethod.POST)
    public ResultMsg add(@RequestBody WorksInfo worksInfo)
            throws IOException, DataNotFoundException {
        Works u = null;
        if (null == worksInfo.getId() || 1 > worksInfo.getId()) {
            u = new Works();
        } else {
            u = (Works) worksService.findById(worksInfo.getId());
            if (!Base.isValid(u))
                u = new Works();
        }
        u.setHairdresser(null);
        if (null != worksInfo.getHairdresserId()
                && 0 < worksInfo.getHairdresserId()) {
            Hairdresser hairdresser = (Hairdresser) hairdresserService
                    .findById(worksInfo.getHairdresserId());
            if (Base.isValid(hairdresser))
                u.setHairdresser(hairdresser);
        }
        u.setImage(null);
        if (null != worksInfo.getImageId() && 0 < worksInfo.getImageId()) {
            Image image = (Image) imageService.findById(worksInfo.getImageId());
            if (Base.isValid(image))
                u.setImage(image);
        }
        u.setName(worksInfo.getName());
        u.setContent(worksInfo.getContent());
        u.setStatus(worksInfo.getStatus());
        u.setWtype(worksInfo.getWtype());
        u.setPutop(worksInfo.getPutop());
        if (null == u.getId())
            worksService.add(u);
        else
            worksService.update(u);
        return new ResultMsg("200",
                messages.getMessage("success", null, "SUCCESS", null),
                new Date());
    }

    @ApiIgnore()
    @ApiOperation(value="删除作品", notes="根据URI的id来指定删除对象")
    @ApiImplicitParam(name = "id", value = "作品ID", required = true, paramType = "path", dataType = "int")
    @PreAuthorize("hasAnyRole('ADMIN') || hasPermission(#id, 'selfWorksById')")
    @RequestMapping(value="/{id}", method=RequestMethod.DELETE)
    public ResultMsg delete(@PathVariable Integer id) {
        worksService.delete(id);
        return new ResultMsg("200", messages.getMessage("success", null, "SUCCESS", null), new Date());
    }
    
    @ApiOperation(value="删除作品", notes="根据POST的id列表来指定删除对象，可批量")
    @ApiImplicitParam(name = "ids", value = "作品ID集", required = true, dataType = "Ids")
    @RequestMapping(value="/delete", method=RequestMethod.DELETE)
    public ResultMsg Batchdelete(@RequestBody Ids ids) {
        worksService.delete(ids.getIds());
        return new ResultMsg("200", messages.getMessage("success", null, "SUCCESS", null), new Date());
    }
    
    @ApiOperation(value="更新作品详细信息", notes="根据URI的id来指定更新对象，并根据传过来的works信息来更新作品详细信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "作品ID", required = true, paramType = "path", dataType = "int"),
            @ApiImplicitParam(name = "works", value = "待更新的作品详细实体works", required = true, dataType = "Works")
    })
    @RequestMapping(value="/{id}", method=RequestMethod.PUT)
    public ResultMsg update(@PathVariable Integer id, @RequestBody Works works) throws DataNotFoundException {
        Works u = (Works) worksService.findById(id);
        if (null == u) {
            throw new DataNotFoundException(Works.class.getName());
        }
        works.setId(id);
        worksService.update(works);
        return new ResultMsg("200", messages.getMessage("success", null, "SUCCESS", null), new Date());
    }
    
    @ApiOperation(value="商家端对作品进行审核", notes="根据URI的id来指定审核对象")
    @ApiImplicitParam(name = "id", value = "作品ID", required = true, paramType = "path", dataType = "int")
    @RequestMapping(value="/check/{id}", method=RequestMethod.GET)
    public ResultMsg check(@PathVariable Integer id) throws DataNotFoundException {
        Works u = (Works) worksService.findById(id);
        if (null == u) {
            throw new DataNotFoundException(Works.class.getName());
        }
        u.setStatus(WorksStatus.NORMAL);
        worksService.update(u);
        return new ResultMsg("200", messages.getMessage("success", null, "SUCCESS", null), new Date());
    }

    @ApiOperation(value="获取作品详细信息", notes="根据URI的id来获取作品详细信息")
    @ApiImplicitParam(name = "id", value = "作品ID", required = true, paramType = "path", dataType = "int")
    @RequestMapping(value="/{id}", method=RequestMethod.GET)
    @Transactional
    public Works load(@PathVariable Integer id) throws DataNotFoundException {
        Works u = (Works) worksService.findById(id);
        if (null == u) {
            throw new DataNotFoundException(Works.class.getName());
        }
        Hairdresser hairdresser = u.getHairdresser();
        hairdresser.setWorkses(null);
        u.getImage().setWorkses(null);
        return u;
    }
    
    @ApiOperation(value="商家端获取作品列表", notes="根据提交的分页信息列出所以作品信息")
    @ApiImplicitParam(name = "pageConf", value = "分页信息实体", required = true, dataType = "PageConf")
    @RequestMapping(value={"/list"}, method=RequestMethod.POST)
    public MapList<WorksInfo> list(@RequestBody PageConf pageConf) {
        List<Works> u = null;
        Long allCount = null;
        Object o = worksService.findAllByPage(pageConf);
        if (o instanceof Page) {
            allCount = ((Page<Works>) o).getTotalElements();
            u = ((Page<Works>) o).getContent();
        } else {
            allCount = (long) ((List<Works>) o).size();
            u = (List<Works>) o;
        }
        List<WorksInfo> ul = new ArrayList<WorksInfo>();
        for (Works c : u) {
            WorksInfo wi = new WorksInfo();
            wi.setId(c.getId());
            wi.setContent(c.getContent());
            if (null != c.getHairdresser()) {
                wi.setCmark(c.getHairdresser().getCmark());
                wi.setHairdresserId(c.getHairdresser().getId());
                wi.setHairdresserName(c.getHairdresser().getName());
            }
            wi.setName(c.getName());
            if (null != c.getImage())
                wi.setImageId(c.getImage().getId());
            if (null != c.getHairdresser() && null != c.getHairdresser().getShop()) {
                wi.setShopId(c.getHairdresser().getShop().getId());
                wi.setShopName(c.getHairdresser().getShop().getName());
            }
            wi.setStatus(c.getStatus());
            wi.setWtype(c.getWtype());
            wi.setCreatedate(c.getModifydate());
            wi.setPutop(c.getPutop());
            ul.add(wi);
        }
        return new MapList<WorksInfo>(allCount, ul);
    }

    // --------------------- 业务具体接口 ---------------------
    
    @ApiOperation(value = "发型师端获取作品类型列表", notes = "返回系统支持的作品类型")
    @PreAuthorize("hasAnyRole('ADMIN', 'HAIRDRE')")
    @RequestMapping(value = { "/type/list" }, method = RequestMethod.GET)
    public MapList<String> list4WorksType() throws RequestParamterException {
        Long allCount = 0L;
        List<String> list = new ArrayList<String>();
        for (WorksType wtype : WorksType.values()) {
            list.add(wtype.name());
            allCount++;
        }
        return new MapList<String>(allCount, list);
    }

    @ApiOperation(value="客户端获取指定发型师的作品列表", notes="根据提交的分页信息列出发型师的所有作品信息")
    @ApiImplicitParam(name = "pageConf", value = "分页信息实体", required = true, dataType = "PageConf")
    @PreAuthorize("hasAnyRole('ADMIN', 'CLIENT')")
    @RequestMapping(value={"/hairdresser/{id}/list"}, method=RequestMethod.POST)
    public MapList<WorksInfo> listByHairdresserId(@RequestBody PageConf pageConf, @PathVariable Integer id) throws RequestParamterException {
        return listWorks(pageConf, id, true);
    }
    
    @ApiOperation(value="发型师端获取自己的作品列表", notes="根据提交的分页信息列出发型师自己的所有作品信息")
    @ApiImplicitParam(name = "pageConf", value = "分页信息实体", required = true, dataType = "PageConf")
    @PreAuthorize("hasAnyRole('ADMIN', 'HAIRDRE')")
    @RequestMapping(value={"/hairdresser/list"}, method=RequestMethod.POST)
    public MapList<WorksInfo> list4HairdresserSelf(@RequestBody PageConf pageConf) throws RequestParamterException {
        XmUser xmUser = (XmUser) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        if (0 == xmUser.getHairdresserid()) {
            throw new RequestParamterException("当前用户非发型师用户，查无发型师信息");
        }
        return listWorks(pageConf, xmUser.getHairdresserid(), false);
    }
    
    public MapList<WorksInfo> listWorks(PageConf pageConf, Integer id, Boolean forClient) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("hairdresserid", id);
        if (forClient)
            map.put("forClient", forClient);
        Page<WorksInfo> u = (Page<WorksInfo>) worksService.findAllByPage(pageConf, map);
        Long allCount = u.getTotalElements();
        return new MapList<WorksInfo>(allCount, u.getContent());
    }

    @ApiOperation(value="发型师创建作品", notes="以表单方式提交作品信息，当前用户必须是发型师或是管理员，并且必须有发型师信息")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "name", value = "作品名称", required = true, dataType = "string", paramType="form"),
        @ApiImplicitParam(name = "wtype", value = "作品类型", required = true, dataType = "string", paramType="form"),
        @ApiImplicitParam(name = "content", value = "作品描述", required = true, dataType = "string", paramType="form"),
        @ApiImplicitParam(name = "file", value = "作品图片文件", required = true, dataType = "file", paramType="form")
    })
    @PreAuthorize("hasAnyRole('ADMIN', 'HAIRDRE')")
    @RequestMapping(value="/hairdresser", method=RequestMethod.POST)
    public ResultMsg createWorks(@RequestParam String name, @RequestParam String wtype, @RequestParam String content,
            @RequestPart MultipartFile file) throws IOException, RequestParamterException {
        XmUser xmUser = (XmUser) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        if (0 == xmUser.getHairdresserid()) {
            throw new RequestParamterException("当前用户非发型师用户，查无发型师信息");
        }
        Hairdresser hairdresser = (Hairdresser) hairdresserService.findById(xmUser.getHairdresserid());
        Works works = new Works();
        works.setHairdresser(hairdresser);
        works.setName(name);
        works.setWtype(WorksType.valueOf(wtype));
        works.setContent(content);
        Image image = new Image();
        image.setFile(file.getBytes());
        works.setImage(image);
        worksService.add(works);
        return new ResultMsg("200", messages.getMessage("success", null, "SUCCESS", null), new Date());
    }
}
